import os.path
import tkinter as tk
from tkinter import ttk, filedialog
import requests
import json
import re
import configparser
from test_tools.class_excel import Writer

try:
    from docx import Document
except ImportError:
    Document = None
    print("检测到docx导入失败，请按后续解决方案处理")


class APITestGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("智能接口用例生成器")
        self.template_path = os.path.abspath("../test_cases/ai_接口用例.xlsx")

        # 初始化配置
        self.load_config()
        self.check_dependencies()

        self.create_widgets()
        self.interfaces = []

    def load_config(self):
        """加载配置文件"""
        self.config = configparser.ConfigParser()
        self.config.read('config.ini')

        # API配置
        self.api_url = self.config.get('API', 'url', fallback="https://api.siliconflow.cn/v1/chat/completions")
        self.api_key = self.config.get('API', 'key', fallback="sk-symlcsyhmmztheoxllyxgwxcjvyexytuadwoksowlgsiqtwb")

        # 网络配置
        self.proxy_config = {
            "enable": self.config.getboolean('Network', 'proxy_enable', fallback=False),
            "http": self.config.get('Network', 'http_proxy', fallback=""),
            "https": self.config.get('Network', 'https_proxy', fallback="")
        }
        self.ssl_verify = self.config.get('Network', 'ssl_verify', fallback="False") == "True"

    def check_dependencies(self):
        """检查依赖"""
        if Document is None:
            self.show_error_dialog(
                "缺少python-docx库，请执行以下命令安装：\n\npip install python-docx\n\n或使用国内镜像：\npip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple")
            self.root.destroy()

    def show_error_dialog(self, message):
        """显示错误对话框"""
        error_dialog = tk.Toplevel()
        error_dialog.title("环境依赖错误")
        ttk.Label(error_dialog, text=message, wraplength=400).pack(padx=20, pady=20)
        ttk.Button(error_dialog, text="确定", command=error_dialog.destroy).pack(pady=10)

    def create_widgets(self):
        """创建界面组件"""
        main_frame = ttk.Frame(self.root)
        main_frame.pack(padx=10, pady=5, fill="both", expand=True)

        # 文档上传区域
        upload_frame = ttk.LabelFrame(main_frame, text="接口文档处理")
        upload_frame.pack(fill="x", pady=5)

        self.btn_upload = ttk.Button(upload_frame, text="上传Word文档", command=self.upload_doc)
        self.btn_upload.pack(side=tk.LEFT, padx=5)

        self.btn_generate = ttk.Button(upload_frame, text="生成测试用例",
                                       command=self.start_generation, state=tk.DISABLED)
        self.btn_generate.pack(side=tk.LEFT, padx=5)

        # 状态栏
        self.status = ttk.Label(self.root, text="就绪", relief=tk.SUNKEN)
        self.status.pack(side=tk.BOTTOM, fill=tk.X)

    def upload_doc(self):
        """上传Word文档"""
        file_path = filedialog.askopenfilename(filetypes=[("Word文档", "*.docx")])
        if file_path:
            try:
                self.parse_word_doc(file_path)
                self.btn_generate.config(state=tk.NORMAL)
                self.status.config(text="文档解析完成，点击生成用例")
            except Exception as e:
                self.status.config(text=f"文档解析失败：{str(e)}")

    def parse_word_doc(self, doc_path):
        """解析Word文档"""
        doc = Document(doc_path)
        self.interfaces = []
        current_interface = {}

        for para in doc.paragraphs:
            text = para.text.strip()

            # 解析接口定义
            if re.match(r'^接口[0-9]+：', text):
                if current_interface:
                    self.interfaces.append(current_interface)
                current_interface = {
                    "name": text.split("：", 1)[1],
                    "method": "POST",
                    "path": "",
                    "params": [],
                    "responses": []
                }
            elif text.startswith("请求方法："):
                current_interface["method"] = text.split("：", 1)[1].upper()
            elif text.startswith("请求路径："):
                current_interface["path"] = text.split("：", 1)[1]
            elif text.startswith("请求参数："):
                params_text = text.split("：", 1)[1]
                current_interface["params"] = self.parse_params(params_text)
            elif text.startswith("响应示例："):
                response_text = text.split("：", 1)[1]
                current_interface["responses"].append(response_text)

        if current_interface:
            self.interfaces.append(current_interface)

    def parse_params(self, params_text):
        """解析参数文本"""
        params = []
        param_items = params_text.split(";")
        for item in param_items:
            if ":" in item:
                name, desc = item.split(":", 1)
                params.append({
                    "name": name.strip(),
                    "type": desc.strip().split(" ")[0],
                    "required": "必填" in desc,
                    "desc": desc
                })
        return params

    def start_generation(self):
        """启动生成流程"""
        self.btn_generate.config(state=tk.DISABLED)
        try:
            writer = Writer()
            writer.copy_open(self.template_path, "result_HTTP接口用例.xlsx")

            for interface in self.interfaces:
                self.generate_interface_cases(writer, interface)

            writer.save_close()
            self.status.config(text="测试用例生成完成！")
        except Exception as e:
            self.status.config(text=f"生成失败：{str(e)}")
        finally:
            self.btn_generate.config(state=tk.NORMAL)

    def generate_interface_cases(self, writer, interface):
        """生成单个接口的测试用例"""
        # 基础设置
        base_data = [
            ["", "基础设置", "", "设置地址", "set_url", f"http://api.example.com{interface['path']}", "", "", "", ""],
            ["", "", "", "添加请求头", "add_header", "Content-Type", "application/json", "", "", ""]
        ]
        self.write_to_excel(writer, "接口流程", base_data)

        # 正常流程
        normal_data = [
            ["", "正常流程", "", interface['name'], "post", interface['name'],
             self.build_payload(interface['params']), "", "", ""],
            ["", "", "", "断言状态码", "assert_equal", "status_code", "200", "", "", ""]
        ]
        self.write_to_excel(writer, "接口流程", normal_data)

        # 异常流程
        error_data = [
            ["", "异常流程", "", "错误参数测试", "post", interface['name'],
             self.build_invalid_payload(interface['params']), "", "", ""],
            ["", "", "", "断言错误信息", "assert_contains", "error", "", "", "", ""]
        ]
        self.write_to_excel(writer, "接口流程", error_data)

    def build_payload(self, params):
        """构建有效载荷"""
        return "&".join([f"{p['name']}={self.get_sample_value(p)}" for p in params])

    def get_sample_value(self, param):
        """生成示例值"""
        type_map = {
            "string": "test_value",
            "int": "123",
            "boolean": "true",
            "float": "3.14"
        }
        return type_map.get(param['type'].lower(), "test_data")

    def build_invalid_payload(self, params):
        """构建无效载荷"""
        return "&".join([f"{p['name']}=" for p in params if p['required']])

    def write_to_excel(self, writer, sheet_name, data):
        """写入Excel"""
        writer.set_sheet(sheet_name)
        start_row = writer.wb[sheet_name].max_row + 1

        for row_idx, row_data in enumerate(data):
            for col_idx, value in enumerate(row_data[:9]):
                if value:
                    writer.write(start_row + row_idx, col_idx, value)


if __name__ == "__main__":
    root = tk.Tk()
    app = APITestGenerator(root)
    root.geometry("500x150")
    root.mainloop()